﻿using Castle.DynamicProxy;
using Microsoft.Extensions.DependencyInjection;
using static _06_AOP.BusinessLogic;
using static _06_AOP.DynamicProxyExample;
using static _06_AOP.EmitExample;
using static _06_AOP.PipelineExample;
using static _06_AOP.StaticProxyExample;

namespace _06_AOP
{
    internal class Program
    {
        static void Main(string[] args)
        {
            Dobasic();
        }

        public static void Dobasic()
        {
            BasicExample.A();
        }

        /// <summary>
        /// 静态代理
        /// </summary>
        public static void TestStaticProxy()
        {
            //目标对象
            IPhoneService target = new PhoneService("10088", "你好啊！");
            //切面1：验证，实现IPhoneService标准
            IPhoneService proxy1 = new PhoneServiceProxy1(target);
            //切面2：加速，实现IPhoneService标准
            IPhoneService proxy2 = new PhoneServiceProxy2(proxy1);
            //执行
            proxy2.Send();
        }
        /// <summary>
        /// Castle.Core自动生成代理类
        /// </summary>
        public static void TestDynamicProxy1()
        {
            //创建代理生成器
            var generator = new ProxyGenerator();
            var target1 = new PhoneService("10088", "你好啊！");
            var target2 = new EmailService("1123@116.com", "你好啊！");
            var interceptor1 = new ShareInterceptor1();//代理1，拦截器1，不需要去实现指定的标准
            var interceptor2 = new ShareInterceptor2();//代理2，拦截器2，不需要去实现指定的标准
            //使用代理1和代理2去代理手机的标准
            IPhoneService dynamicProxy1 = generator.CreateInterfaceProxyWithTarget<IPhoneService>(target1, interceptor1, interceptor2);
            dynamicProxy1.Send();
            //代理邮件的标准
            IEmailService dynamicProxy2 = generator.CreateInterfaceProxyWithTarget<IEmailService>(target2, interceptor1, interceptor2);
            dynamicProxy2.Send();
        }
        /// <summary>
        /// 手动编写Castle.Core代理类
        /// </summary>
        public static void TestDynamicProxy2()
        {
            //创建代理生成器
            var target1 = new PhoneService("10088", "你好啊！");
            var interceptor1 = new ShareInterceptor1();//代理1，拦截器1，不需要去实现指定的标准
            var interceptor2 = new ShareInterceptor2();//代理2，拦截器2，不需要去实现指定的标准
            IPhoneService proxy = new CastelPhoneServiceProxy(target1, new IInterceptor[]
            {
                interceptor1,
                interceptor2,
            });
            proxy.Send();
        }
        /// <summary>
        /// 容器支持
        /// </summary>
        public static void TestDynamicProxy4()
        {
            var services = new ServiceCollection();
            services.AddScoped<DbContext>();
            var generator = new ProxyGenerator();
            //泛型-不支持动态注入
            services.AddScoped(sp => 
            {
                //通过容器解析依赖
                var target = ActivatorUtilities.CreateInstance<AService>(sp);
                return generator.CreateClassProxyWithTarget(target);
            });
            //反射-可以扫描批量注入
            services.AddScoped(typeof(AService), sp =>
            {
                //通过容器解析依赖
                var target = ActivatorUtilities.CreateInstance(sp, typeof(AService));
                return generator.CreateClassProxyWithTarget(target);
            });
        }
        /// <summary>
        /// 通过Emit创建一个类
        /// </summary>
        public static void TestEmit()
        {
            var target1 = new PhoneService("10088", "你好啊！");
            var interceptor1 = new EmitInteceptor1();//代理1，拦截器1，不需要去实现指定的标准
            var interceptor2 = new EmitInteceptor2();//代理2，拦截器2，不需要去实现指定的标准
            IEmitService obj = EmitProxyGenerator.Create<IEmitService>(target1, interceptor1, interceptor2);
            obj.Send();
        }
        /// <summary>
        /// 管道1-委托
        /// </summary>
        public static void TestPipeline1()
        {
            var app = new ApplicationBuilder();
            app.Use(next =>
            {
                RequestDelegate current = async context =>
                {
                    Console.WriteLine("身份已验证开始");
                    await next(context);
                    Console.WriteLine("身份已验证结束");
                };
                return current;
            });
            app.Use(next =>
            {
                return async context =>
                {
                    Console.WriteLine("资源已授权关闭");
                    await next(context);
                    Console.WriteLine("资源已授权关闭");
                };
            });
            app.Use(next =>
            {
                return context =>
                {
                    Console.WriteLine("Hello world!");
                    return Task.CompletedTask;
                };
            });
            var pipeline = app.Build();
            pipeline(new HttpContext());
        }
        /// <summary>
        /// 管道1-简化委托
        /// </summary>
        public static void TestPipeline2()
        {
            var app = new ApplicationBuilder();
            app.Use(async (context, next) =>
            {
                Console.WriteLine("身份已验证开始");
                await next(context);
                Console.WriteLine("身份已验证结束");
            });
            app.Use(next =>
            {
                RequestDelegate current = async context =>
                {
                    Console.WriteLine("资源已授权关闭");
                    await next(context);
                    Console.WriteLine("资源已授权关闭");
                };
                return current;
            });
            app.Run(context =>
            {
                Console.WriteLine("Hello world!");
                return Task.CompletedTask;
            });
            var pipeline = app.Build();
            pipeline(new HttpContext());
        }
        /// <summary>
        /// 管道2-接口
        /// </summary>
        public static void TestPipeline3()
        {
            var web = new WebHost();
            web.AddFilter(new Filter1());
            web.AddFilter(new Filter2());
            web.Exeucte(new HttpContext(), new HelloServlet());
        }
    }
}